﻿using DFGJ.WMS_PDA.WebAPI.CfgFile;
using DFGJ.WMS_PDA.WebAPI.Extensions;
using DFGJ.WMS_PDA.WebAPI.Utility.Filters;
using DFGK.WMS.Common.Result;
using DFGK_WMS.Context;
using DFGK_WMS.IRepository;
using DFGK_WMS.IRepository.IService;
using DFGK_WMS.IRepository.蒙牛;
using DFGK_WMS.Model;
using DFGK_WMS.Model.DTO;
using DFGK_WMS.Model.Models;
using DFGK_WMS.Model.Models.PDA;
using DFGK_WMS.Repository;
using DFGK_WMS.WebAPI.AttributeFile;
using DFGK_WMS.WebAPI.Controllers.Result;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileSystemGlobbing.Internal;
using NPOI.POIFS.Crypt.Dsig;
using NPOI.SS.Formula.Functions;
using NPOI.SS.Formula.PTG;
using SqlSugar;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.RegularExpressions;
namespace DFGJ.WMS_PDA.WebAPI.Controllers.PDA.蒙牛
{
    [Route("api/[controller]")]
    [ApiController]
    public class MNPDAHandlerController : ControllerBase
    {

        #region Service 
        private readonly ILogger<PDAHandlerController> _Logger;

        private readonly DFGK_DB _dbContext;

        private readonly ISqlSugarClient _Client;

        //入库单明细 
        private readonly ITReceivingOrderDetailRepository _TRecevingDetail;

        //收货单
        private readonly IMNTReceivingBillRepository _TReceivingBill;

        //站台
        private readonly ITStationRepository _TStation;

        //入库垛  
        private readonly IStackingStorageRepository _StackingStorage;

        //倒垛
        private readonly IStackingStorageService _IStackStorageService;
        private readonly ILogRepository logRepository;

        #endregion



        public MNPDAHandlerController
            (ILogger<PDAHandlerController> logger,
             DFGK_DB dbContext,
             ITReceivingOrderDetailRepository orderDetailRepository,
             IMNTReceivingBillRepository tReceivingBill,
             ITStationRepository tStation,
             ISqlSugarClient client,
             IStackingStorageRepository stackingStorage,
             IStackingStorageService iStackStorageService,
             ILogRepository logRepository
           )

        {
            _Logger = logger;
            _dbContext = dbContext;
            _TRecevingDetail = orderDetailRepository;
            _TReceivingBill = tReceivingBill;
            _TStation = tStation;
            _Client = client;
            _StackingStorage = stackingStorage;
            _IStackStorageService = iStackStorageService;
            this.logRepository = logRepository;
        }

        /// <summary>
        /// 逻辑分区
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("GetDictItems")]
        public IActionResult GetDictItems()
        {
            try
            {
                var list = _TReceivingBill.GetDictItems();
                if (list != null && list.Count != 0)
                {
                    return Ok(BaseResult.Result(list, "查询成功", "500"));
                }
                return Ok(BaseResult.Result(null, "查询失败", "500"));
            }
            catch (Exception ex)
            {
                return Ok(BaseResult.Result(null, "查询失败", "500"));
            }
        }


        #region 获取入库单明细数据
        /// <summary>
        /// 获取入库单明细数据
        /// </summary>
        /// <param name="pageIndex">当前页</param>
        /// <param name="pageSize">页容量</param>
        /// <param name="wareHouseId">库房Id</param>
        /// <param name="searchaString">关键字</param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetOrderListAsync/{pageIndex}/{pageSize}")]
        public async Task<IActionResult> GetOrderListAsync(int pageIndex, int pageSize, int? wareHouseId, string? searchaString = null)
        {
            try
            {

                ISugarQueryable<TReceivingOrderDetail> iQueryable = _Client.Queryable<TReceivingOrderDetail>().Where(it => it.Status >= 1 && it.Status < 4);

                iQueryable = iQueryable.WhereIF(wareHouseId != null, it => it.WarehouseId == wareHouseId);

                if (!string.IsNullOrWhiteSpace(searchaString))
                {
                    iQueryable = iQueryable.Where(t => t.OrderSn == searchaString || t.BatchNo == searchaString || t.OwnerName.Contains(searchaString) || t.MaterialCode == searchaString);
                }
                int totalCount = iQueryable.Count();
                PagingData<TReceivingOrderDetail> pagingData = new PagingData<TReceivingOrderDetail>()
                {
                    DataList = iQueryable.OrderBy(it => it.Id).ToPageList(pageIndex, pageSize),
                    RecordCount = totalCount
                };

                ApiResult<PagingData<TReceivingOrderDetail>> apiResult = new ApiResult<PagingData<TReceivingOrderDetail>>()
                {
                    Data = pagingData,
                    Success = true,
                    Code = "200"
                };
                return await Task.FromResult(new JsonResult(apiResult));

            }
            catch (Exception ex)
            {
                _Logger.LogError(ex.Message);

                return await Task.FromResult(new JsonResult(new ApiBaseResult { Success = false, Message = ex.Message }));

            }


        }

        /// <summary>
        /// 根据订单号查询入库单
        /// </summary>
        /// <param name="OrderSn"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetReceiving")]
        public IActionResult GetReceiving(string OrderSn)
        {
            if (OrderSn is null)
            {
                return Ok(BaseResult.Result(null, "订单号不能为空", "500"));
            }
            var receivingOrder = _Client.Queryable<TReceivingOrderDetail>().Where(r => r.OrderSn == OrderSn && r.Status == 3).ToList();
            if (receivingOrder.Count > 0)
            {
                return Ok(BaseResult.Result(new
                {
                    count = receivingOrder.Count,
                    nowcount = receivingOrder.Where(r => r.Status == 4).Count() + 1,
                    data = receivingOrder.FirstOrDefault()

                }, "", "200"));
            }

            return Ok(BaseResult.Result(null, "订单已经没有数据了", "200"));
        }

        #endregion

        /// <summary>
        /// 入库
        /// </summary>
        /// <param name="PalletCode">托盘码</param>
        /// <returns></returns>
        [HttpPost]
        [Route("ExecCreateInventory")]
        [TypeFilter(typeof(LogActionFilter))]
        [HttpIdempotent(WaitMillisecond = 10000, CacheMillisecond = 3000)]
        public IActionResult ExecCreateInventory(StartInventoryDTO startInventoryDTO)
        {
            ApiBaseResult baseResult = new ApiBaseResult();
            if (string.IsNullOrEmpty(startInventoryDTO.PalletCode) || string.IsNullOrEmpty(startInventoryDTO.ActualLocation))
            {
                baseResult.Code = "500";
                baseResult.Success = false;
                baseResult.Message = "参数有误";
                return Ok(baseResult);
            }

            var stackingStorage = _Client.Queryable<TStackingStorage>().First(s => s.Status == 1 && s.PalletBarcode == startInventoryDTO.PalletCode);
            if (stackingStorage is null)
            {
                baseResult.Code = "500";
                baseResult.Success = false;
                baseResult.Message = "无组垛信息";
                return Ok(baseResult);
            }

            var cell = _Client.Queryable<TCell>().First(c => c.Code == startInventoryDTO.ActualLocation);
            if (cell is null)
            {
                baseResult.Code = "500";
                baseResult.Success = false;
                baseResult.Message = "仓位不存在" + startInventoryDTO.ActualLocation;
                return Ok(baseResult);
            }
            if (stackingStorage.ExpectedLocation != startInventoryDTO.ActualLocation)
            {
                if (cell.FullStatus == 1 || cell.Status == 2 || cell.IsLock == true)
                {
                    baseResult.Code = "500";
                    baseResult.Success = false;
                    baseResult.Message = "仓位已被占用" + startInventoryDTO.ActualLocation;
                    return Ok(baseResult);
                }
            }

            var orderDetail = _Client.Queryable<TReceivingOrderDetail>().First(x => x.Id == stackingStorage.RelatedOrderDetailId);
            TStation station = _Client.Queryable<TStation>().First(r => r.WhId == orderDetail.WarehouseId);
            DFGK_WMS.Model.Models.PalletBindMaterialModel palletBindMaterialModel = new DFGK_WMS.Model.Models.PalletBindMaterialModel()
            {
                PalletBarcode = startInventoryDTO.PalletCode,
                MaterialPackageBindModel = new DFGK_WMS.Model.Models.MaterialPackageBindModel()
                {
                    OrderDetailId = orderDetail.Id,
                    MaterialCode = orderDetail.MaterialCode,
                    Qty = orderDetail.Qty,
                }
            };
            string errMsg = string.Empty;
            var result = _IStackStorageService.ExecCreateInstruct(out errMsg, orderDetail, station, palletBindMaterialModel, startInventoryDTO.ActualLocation);

            string uname = HttpContext.User.FindFirstValue("UserName");
            string runame = HttpContext.User.FindFirstValue("RealName");
            int uid = Convert.ToInt32(HttpContext.User.FindFirstValue("Id"));
            string? ip = HttpContext.Connection.RemoteIpAddress?.ToString();
            TLog logg = new TLog();
            logg.LogType = 1;
            logg.ActionType = 4;
            logg.ModuleName = "添加入库";
            logg.UserName = uname;
            logg.RealName = runame;
            logg.UserId = uid;
            logg.Description = result ? uname + "入库成功" : uname + "入库失败: " + errMsg;
            logg.Ipaddress = ip;
            logRepository.AddTLod(logg);
            if (!result)
            {
                baseResult.Code = "500";
                baseResult.Success = false;
                baseResult.Message = errMsg;
                return Ok(baseResult);
            }
            baseResult.Code = "200";
            baseResult.Success = true;
            baseResult.Message = "操作成功";
            return new JsonResult(baseResult);
        }

        /// <summary>
        /// 查询入库单
        /// </summary>
        /// <param name="PalletCode"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetReceivingBill")]
        public IActionResult GetReceivingBill(string PalletCode)
        {
            var stackingStorage = _Client.Queryable<TStackingStorage>().First(s => s.Status == 1 && s.PalletBarcode == PalletCode);

            if (stackingStorage is null)
            {
                return Ok(BaseResult.Result(null, "无组垛信息", "500"));
            }

            var orderDetail = _Client.Queryable<TReceivingOrderDetail>().First(x => x.Id == stackingStorage.RelatedOrderDetailId && x.Status == 3);
            if (orderDetail is null)
            {
                return Ok(BaseResult.Result(null, "入库单查询失败", "200"));
            }
            return Ok(BaseResult.Result(new
            {
                OrderDetailId = orderDetail.Id,
                PallteCode = stackingStorage.PalletBarcode,
                cell = stackingStorage.ExpectedLocation,
                OrderNo = orderDetail.OrderSn,
                MaterialCode = orderDetail.MaterialCode,
                Num = orderDetail.StackedQty,
            }, "成功", "200"));
        }

        /// <summary>
        /// 判断托盘是否可用
        /// </summary>
        /// <param name="PalletCode"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("PalletVerify")]
        public IActionResult PalletVerify(string PalletCode)
        {
            var pallet = _Client.Queryable<TPallet>().First(p => p.PalletBarcode == PalletCode);
            ApiBaseResult baseResult = new ApiBaseResult();
            if (pallet is null)
            {
                baseResult.Code = "200";
                baseResult.Success = false;
                baseResult.Message = "托盘不存在";
                return Ok(baseResult);
            }
            TStackingStorage storageModel = _Client.Queryable<TStackingStorage>().First(r => r.Status == 1 && r.PalletBarcode == PalletCode);
            if (storageModel != null)
            {
                baseResult.Code = "200";
                baseResult.Success = false;
                baseResult.Message = "托盘已在组垛中";
                return Ok(baseResult);
            }
            var inventory = _Client.Queryable<TInventory>().First(r => r.PalletBarcode == PalletCode);
            if (inventory is not null)
            {
                baseResult.Code = "200";
                baseResult.Success = false;
                baseResult.Message = "当前托盘已在库存中";
                return Ok(baseResult);
            }

            baseResult.Code = "200";
            baseResult.Success = true;
            baseResult.Message = "";
            return new JsonResult(baseResult);
        }

        /// <summary>
        /// 判断小批号是否存在
        /// </summary>
        /// <param name="SmallBatchNo"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetlittleBatchNo")]
        public IActionResult GetlittleBatchNo(string SmallBatchNo)
        {
            var recevingorder = _Client.Queryable<TReceivingOrderDetail>().First(r => r.SmallBatchNo == SmallBatchNo);
            ApiBaseResult baseResult = new ApiBaseResult();
            if (recevingorder is not null)
            {
                baseResult.Code = "500";
                baseResult.Success = false;
                baseResult.Message = "有相同的小批次号";
                return Ok(baseResult);
            }
            baseResult.Code = "200";
            baseResult.Success = true;
            baseResult.Message = "";
            return new JsonResult(baseResult);
        }

        /// <summary>
        /// 查询全部收货单(分页)
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="status"></param>
        /// <param name="warehouseId"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetReceivingBillList")]
        public IActionResult GetReceivingBillList(int? status = 3, int? warehouseId = 0, int pageIndex = 1, int pageSize = 10)
        {
            if (pageIndex <= 0 || pageSize <= 0)
            {
                return Ok(BaseResult.Result("400", "分页条件有误！"));
            }
            int totalCount;

            var list = _TReceivingBill.GetReceivingBillList(startTime: null ,endTime: null,customerId: null, status.GetValueOrDefault(), warehouseId.GetValueOrDefault(), pageIndex, pageSize, out totalCount).ToList();
            if (list.Count <= 0)
            {
                return Ok(BaseResult.Result(list, "目前没有收货单！", "200", totalCount));
            }
            if (list != null)
            {
                return Ok(BaseResult.Result(list, "查询成功！", "200", totalCount));
            }
            return Ok(BaseResult.Result(null, "查询失败！", "500", 0));
        }

        /// <summary>
        /// 查询收货单的商品
        /// </summary>
        /// <param name="receivingBillId"></param>
        /// <param name="materialCodeArticlebarcode"></param>
        /// <param name="batchno"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetReceivingBillGoodsDeatil")]
        public IActionResult GetReceivingBillGoodsDeatil(int receivingBillId, string? materialCodeArticlebarcode)
        {
            ApiBaseResult baseResult = new ApiBaseResult();
            if (receivingBillId <= 0 || materialCodeArticlebarcode is null)
            {
                baseResult.Code = "500";
                baseResult.Success = false;
                baseResult.Message = "参数有误";
                return Ok(baseResult);
            }

            //var material = _Client.Queryable<TMaterial>().First(m => m.Articlebarcode == materialCodeArticlebarcode);

            //if (material is not null)
            //{
            //    materialCodeArticlebarcode = material.Code;
            //}
            //else
            //{
            //    material = _Client.Queryable<TMaterial>().First(m => m.Code == materialCodeArticlebarcode);
            //    if (material is null)
            //    {
            //        baseResult.Code = "500";
            //        baseResult.Success = false;
            //        baseResult.Message = "未查出物料";
            //        return Ok(baseResult);
            //    }
            //    materialCodeArticlebarcode = material.Code;
            //}
            //根据物料编码和数量查询出来收货单明细
            var recevingbilldeta = _Client.Queryable<TReceivingBillDetail>().Where(r => r.BillId == receivingBillId && r.MaterialCode == materialCodeArticlebarcode && r.ReceivedQty < r.Qty).ToList();

            if (recevingbilldeta is null || recevingbilldeta.Count <= 0)
            {
                baseResult.Code = "500";
                baseResult.Success = false;
                baseResult.Message = "未查出物料";
                return Ok(baseResult);
            }
            var res = recevingbilldeta.Select(r => new
            {
                r.BatchNo,
                r.BatchNoExplain,
                r.BillId,
                r.BillLineNo,
                r.BillNo,
                r.CheckedQty,
                r.ConfirmDate,
                r.CreateDate,
                r.ExpireDate,
                r.Id,
                r.IsNeedQc,
                r.MaterialCode,
                r.MaterialId,
                r.MaterialName,
                r.MaterialTypeCode,
                r.MaterialTypeName,
                r.NeedCheckQty,
                r.OutFactoryDate,
                r.OwnerId,
                r.OwnerName,
                r.Price,
                r.ProduceFactory,
                r.ProductDate,
                r.PurchaseOrderNo,
                NoReceivedQty = r.Qty - r.ReceivedQty,
                r.ReceivedQty,
                r.Status,
                r.SupplierId,
                r.SupplierName,
                r.TotalPrice
            });
            return Ok(BaseResult.Result(res, "查询成功", "200"));
        }



        /// <summary>
        /// PDA收货入库(蒙牛)
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("BuildCreateStackingStorage")]
        [TypeFilter(typeof(LogActionFilter))]
        [HttpIdempotent(WaitMillisecond = 10000, CacheMillisecond = 3000)]
        public IActionResult BuildCreateStackingStorage(ReceivingBillOrderDto m)
        {
            if (m.Id <= 0)
            {
                return Ok(BaseResult.Result("400", "Id有误！"));
            }
            string message = "";
            m.NowUserId = Convert.ToInt32(HttpContext.User.FindFirstValue("Id"));
            m.NowUserRealName = HttpContext.User.FindFirstValue("UserName");
            List<TCell> Getcell = new List<TCell>();
            bool IsOK = _TReceivingBill.AddPDAReceivingOrderDateil(m, out message, ref Getcell);
            string uname = HttpContext.User.FindFirstValue("UserName");
            string runame = HttpContext.User.FindFirstValue("RealName");
            int uid = Convert.ToInt32(HttpContext.User.FindFirstValue("Id"));
            m.NowUserRealName = uname;//创建人
            m.NowUserId = uid;//创建人id
            string? ip = HttpContext.Connection.RemoteIpAddress?.ToString();
            TLog logg = new TLog();
            logg.LogType = 1;
            logg.ActionType = 4;
            logg.ModuleName = "添加组垛";
            logg.UserName = uname;
            logg.RealName = runame;
            logg.UserId = uid;
            logg.Description = IsOK ? uname + "创建了组垛" : uname + "创建组垛失败: " + message;
            logg.Ipaddress = ip;
            logRepository.AddTLod(logg);
            if (IsOK)
            {
                var iscell = "";
                foreach (var item in Getcell)
                {
                    iscell += item.Name;
                }
                return Ok(BaseResult.Result(true, "分配的仓位为：" + iscell, "200"));
            }
            return Ok(BaseResult.Result(false, message, "500"));
        }

        /// <summary>
        /// 获取小批次号
        /// </summary>
        /// <param name="BatchNo"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetSmallBatchNo")]
        public IActionResult GetSmallBatchNo(string BatchNo)
        {
            if (BatchNo is null || BatchNo == "")
            {
                return Ok(BaseResult.Result("500", "参数有误！"));
            }
            string res = "";
            var data = BatchNo.ToArray();
            if (GetMM(data[4]) == "")
            {
                return Ok(BaseResult.Result("500", "没有查出相对应的月份！"));
            }
            res = res + data[0].ToString();
            res = res + "20" + data[2].ToString() + data[3].ToString();



            res = res + GetMM(data[4]);
            res = res + data[5].ToString() + data[6].ToString();
            res = res + data[1].ToString();
            res = res + data[7].ToString() + data[8].ToString() + data[9].ToString();
            return Ok(BaseResult.Result(res, "成功生成详细批次！", "200"));

        }
        private string GetMM(char zm)
        {
            switch (zm)
            {
                case 'A':
                    return "00";
                case 'B':
                    return "01";
                case 'C':
                    return "02";
                case 'D':
                    return "03";
                case 'E':
                    return "04";
                case 'F':
                    return "05";
                case 'G':
                    return "06";
                case 'H':
                    return "07";
                case 'J':
                    return "08";
                case 'K':
                    return "09";
                case 'L':
                    return "10";
                case 'M':
                    return "11";
                case 'N':
                    return "12";
                case 'O':
                    return "13";
                case 'P':
                    return "14";
                case 'Q':
                    return "15";
                case 'R':
                    return "16";
                case 'S':
                    return "17";
                case 'T':
                    return "18";
                case 'U':
                    return "19";
                case 'V':
                    return "20";
                case 'W':
                    return "21";
                case 'X':
                    return "22";
                case 'Y':
                    return "23";
                case 'Z':
                    return "24";
                default:
                    return "";
            }
        }
    }
}
